package com.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.domain.dto.AppointmentDto;
import com.common.domain.entity.Consultation;
import com.common.domain.entity.Department;
import com.common.domain.entity.ResponseResult;
import com.common.domain.vo.AppointmentSlot;
import com.common.domain.vo.AppointmentVo;
import com.common.domain.vo.CommentVo;
import com.common.domain.vo.ConsultationVo;
import com.common.enums.AppHttpCodeEnum;
import com.common.mapper.ConsultationMapper;
import com.common.mapper.DoctorMapper;
import com.common.service.ConsultationService;
import com.common.util.DateUtil;
import com.common.util.RedisCache;
import com.common.util.SecurityUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class ConsultationServiceImpl extends ServiceImpl<ConsultationMapper, Consultation>
        implements ConsultationService {
    private static final  String SLOT_MORNING = "0";

    private static final Long NUMBER = 5L;

    private static final String KEY_PER = "appointment_";

    @Autowired
    private RedisCache redisCache;


    @Autowired
    private ConsultationMapper consultationMapper;

    @Override
    public ResponseResult submitAppointmentInfo(AppointmentDto appointmentDto) {
        //提交记录
        Long doctorId = appointmentDto.getDoctorId();

        String userKey = SecurityUtils.getUserId() + "_appointmentDto";
        if(redisCache.exists(userKey)){
            return new ResponseResult().ok(AppHttpCodeEnum.OTHER_REQUESTS_ERROR);
        }
        try{
            redisCache.set(userKey, 1, 10L);
            String key = KEY_PER + doctorId + appointmentDto.getAppointmentDate() + appointmentDto.getSlot();

            if(redisCache.exists(key)){
                if(Long.parseLong(redisCache.getCacheObject(key).toString()) >= NUMBER){
                    return  ResponseResult.errorResult(AppHttpCodeEnum.MAXIMUM_NUMBER);
                }
            }else{
                AppointmentSlot dateAppointmentInfo = consultationMapper.getDateAppointmentInfo(doctorId, appointmentDto.getAppointmentDate());
                if(appointmentDto.getSlot().equals(SLOT_MORNING)){
                    if(dateAppointmentInfo.getMorningNumber() >= NUMBER){
                        redisCache.set(key , dateAppointmentInfo.getMorningNumber(), 600L);
                        return  ResponseResult.errorResult(AppHttpCodeEnum.MAXIMUM_NUMBER);
                    }
                }else{
                    if(dateAppointmentInfo.getAfternoonNumber() >= NUMBER){
                        redisCache.set(key , dateAppointmentInfo.getAfternoonNumber(), 600L);
                        return  ResponseResult.errorResult(AppHttpCodeEnum.MAXIMUM_NUMBER);
                    }
                }
            }


            //将数据存入数据库
            Consultation consultation = new Consultation();

            consultation.setDoctorId(doctorId);
            consultation.setUserId(SecurityUtils.getUserId());
            consultation.setSlot(Integer.valueOf(appointmentDto.getSlot()));
            consultation.setStartTime(DateUtil.StringToDate(appointmentDto.getAppointmentDate()));
            consultation.setDetailDesc(appointmentDto.getDesc());

            save(consultation);

            redisCache.incrBy(key);

            //发送邮件纪录
            return new ResponseResult().ok("提交预约成功");
        }catch (Exception e){
            //删除缓存
            return new ResponseResult().ok("预约失败，请稍后再试");
        }finally {
            //删除缓存
            redisCache.remove(userKey);
        }

    }

    @Override
    public ResponseResult updateAppointmentInfo(AppointmentDto appointmentDto) {
        //提交记录
        Long doctorId = appointmentDto.getDoctorId();


        String userKey = SecurityUtils.getUserId() + "_appointmentDto";
        if(redisCache.exists(userKey)){
            return new ResponseResult().ok(AppHttpCodeEnum.OTHER_REQUESTS_ERROR);
        }
        try{
            //判断是否只是修改了备注，如果是就不执行其他逻辑
            Consultation consultation = getById(appointmentDto.getId());
            if(DateUtil.StringToDate(appointmentDto.getAppointmentDate()).equals(consultation.getStartTime())
                    && consultation.getSlot().equals(Integer.valueOf(appointmentDto.getSlot()))){
                consultation.setDetailDesc(appointmentDto.getDesc());
                updateById(consultation);
                return new ResponseResult().ok("修改预约成功");
            }

            redisCache.set(userKey, 1, 10L);
            String key = KEY_PER + doctorId + appointmentDto.getAppointmentDate() + appointmentDto.getSlot();

            if(redisCache.exists(key)){
                if(Long.parseLong(redisCache.getCacheObject(key).toString()) >= NUMBER){
                    return  ResponseResult.errorResult(AppHttpCodeEnum.MAXIMUM_NUMBER);
                }
            }else{
                AppointmentSlot dateAppointmentInfo = consultationMapper.getDateAppointmentInfo(doctorId, appointmentDto.getAppointmentDate());
                if(appointmentDto.getSlot().equals(SLOT_MORNING)){
                    if(dateAppointmentInfo.getMorningNumber() >= NUMBER){
                        redisCache.set(key , dateAppointmentInfo.getMorningNumber(), 600L);
                        return  ResponseResult.errorResult(AppHttpCodeEnum.MAXIMUM_NUMBER);
                    }
                }else{
                    if(dateAppointmentInfo.getAfternoonNumber() >= NUMBER){
                        redisCache.set(key , dateAppointmentInfo.getAfternoonNumber(), 600L);
                        return  ResponseResult.errorResult(AppHttpCodeEnum.MAXIMUM_NUMBER);
                    }
                }
            }
            //将数据存入数据库
            Consultation insert = new Consultation();

            insert.setDoctorId(doctorId);
            insert.setUserId(SecurityUtils.getUserId());
            insert.setSlot(Integer.valueOf(appointmentDto.getSlot()));
            insert.setStartTime(DateUtil.StringToDate(appointmentDto.getAppointmentDate()));
            insert.setDetailDesc(appointmentDto.getDesc());
            insert.setId(appointmentDto.getId());

            updateById(insert);

            redisCache.incrBy(key);

            //发送邮件纪录
            return new ResponseResult().ok("修改预约成功");
        }catch (Exception e){
            //删除缓存
            return new ResponseResult().ok("修改失败，请稍后再试");
        }finally {
            //删除缓存
            redisCache.remove(userKey);
        }

    }

    @Override
    public ResponseResult getDateAppointmentInfo(Long id, String date) {
        AppointmentSlot dateAppointmentInfo = consultationMapper.getDateAppointmentInfo(id, date);

        dateAppointmentInfo.setAfternoonNumber( NUMBER - dateAppointmentInfo.getAfternoonNumber() );
        dateAppointmentInfo.setMorningNumber( NUMBER - dateAppointmentInfo.getMorningNumber() );
        return ResponseResult.okResult(dateAppointmentInfo);
    }

    @Override
    public PageInfo<AppointmentVo> getAppointmentLog(String type, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<AppointmentVo> appointmentVoList = consultationMapper.getAppointmentLog(SecurityUtils.getUserId(), type);

        PageInfo<AppointmentVo> pageInfo = new PageInfo<>(appointmentVoList);

        pageInfo.setList(appointmentVoList);

        return pageInfo;
    }

    @Override
    public ResponseResult cancelAppointmentLog(Long id) {
        Consultation consultation = new Consultation();
        consultation.setId(id);
        consultation.setStatus("2");
        updateById(consultation);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult allConsultationList(Integer pageNum, Integer pageSize, String name, String time, String status) {
        PageHelper.startPage(pageNum,pageSize);
        Long userId = null;
        if(SecurityUtils.getUserId() != 24L){
            userId = SecurityUtils.getUserId();
        }
        List<ConsultationVo> list = consultationMapper.allConsultationList(userId, name, time, status);
        PageInfo<ConsultationVo> pageInfo = new PageInfo<>(list);
        pageInfo.setList(list);

        return ResponseResult.okResult(pageInfo);
    }

    @Override
    public void updateStatus(Long id, String status) {
        Consultation consultation = new Consultation();
        consultation.setId(id);
        consultation.setStatus(status);
        consultation.setEndTime(new Date());
        updateById(consultation);
    }


}
